from wormbane.geometry import Vector
from wormbane.model.thing import Thing

class Cell(Thing):
    is_cell = True
    kind = 'cell'
    pos = None
    monster = None
    boulder = None
    feature = None

    def __init__(self, **kwargs):
        from wormbane.model.feature import Wall

        Thing.__init__(self, **kwargs)
        Wall().move_to(self)

    @property
    def passable(self):
        return (not self.monster and not self.boulder
                and (not self.feature or self.feature.passable))

    @property
    def top_inv(self):
        return self.monster or self.boulder or self.top_item or self.feature

    @property
    def top_item(self):
        for thing in reversed(self.inv):
            if thing.is_item:
                return thing
        return None

    @property
    def items(self):
        return [thing for thing in self.inv if thing.is_item]

    @property
    def char(self):
        thing = self.top_inv
        return thing.char if thing else ' '

    @property
    def neighbors(self):
        level = self.level_env
        if level:
            for dx in (-1, 0, 1):
                for dy in (-1, 0, 1):
                    if dx or dy:
                        pos = self.pos + Vector(dx, dy)
                        cell = level.cells.get(pos)
                        if cell:
                            yield cell

    @property
    def exits(self):
        for cell in self.neighbors:
            offset = self.pos - cell.pos
            diagonal = bool(offset.x and offset.y)
            if (cell.passable
                and not (diagonal and (self.feature.is_door
                                       or cell.feature.is_door))):
                yield cell

    def add_inv(self, thing):
        Thing.add_inv(self, thing)
        if thing.is_monster:
            if self.monster:
                self.monster.move_to(None)
            self.monster = thing
        elif thing.is_boulder:
            if self.boulder:
                self.boulder.move_to(None)
            self.boulder = thing
        elif thing.is_feature:
            if self.feature:
                self.feature.move_to(None)
            self.feature = thing

    def remove_inv(self, thing):
        Thing.remove_inv(self, thing)
        if thing == self.monster:
            self.monster = None
        elif thing == self.boulder:
            self.boulder = None
        elif thing == self.feature:
            self.feature = None
